package com.jesse.eclgy.plug.db;

import cn.hutool.core.util.StrUtil;
import com.jesse.eclgy.plug.callback.OnError;
import com.jesse.eclgy.plug.callback.OnSuccess;
import com.jesse.eclgy.plug.logging.Logger;
import com.jesse.eclgy.plug.logging.LoggerFactory;
import com.jesse.eclgy.plug.wrapper.IWrapper;
import com.jesse.eclgy.plug.wrapper.QueryWrapper;
import lombok.Getter;
import lombok.Setter;
import weaver.conn.RecordSetTrans;

import java.util.*;

/**
 * 泛微数据库 记录集工具
 *
 * @Author: jesse
 * @Date: 2023/6/3 16:13
 */
public class RecordSetPlus extends RecordSetTrans {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 如执行异常
     */
    @Getter
    private Exception exception = new RuntimeException();

    /**
     * 错误回调
     */
    @Setter
    private OnError onError = (ex, sql, params) -> {
        this.exception = ex;
        this.logger.error(StrUtil.format("执行出错，SQL：{},参数：{}", sql, params), ex);
    };
    /**
     * 成功回调
     */
    @Setter
    private OnSuccess onSuccess = (sql, params) -> {
        //  this.logger.info(StrUtil.format("执行成功，SQL：{},参数：{}", sql, params));
    };


    public static RecordSetPlus builder()
    {
        return new RecordSetPlus();
    }

    /**
     * 查询执行
     *
     * @param wrapper
     * @return
     */
    public boolean executeQuery(QueryWrapper wrapper)
    {
        return this.executeQuery(wrapper, this.onError);
    }

    /**
     * 查询执行
     *
     * @param wrapper
     * @param onError
     * @return
     */
    public boolean executeQuery(QueryWrapper wrapper, OnError onError)
    {
        String sql = wrapper.getSql();
        List<Object> params = wrapper.getParams();

        try
        {
            boolean fla = (params == null || params.size() == 0) ? executeQuery(sql) : executeQuery(sql, params);
            this.onSuccess.onSuccess(sql, params);
            return fla;
        } catch (Exception ex)
        {
            onError.OnError(ex, sql, params);
            return false;
        }
    }

    /**
     * 更新执行
     *
     * @param wrapper
     * @return
     */
    public boolean executeUpdate(IWrapper wrapper)
    {
        return this.executeUpdate(wrapper, this.onError);
    }

    /**
     * 更新执行
     *
     * @param wrapper
     * @param onError
     * @return
     */
    public boolean executeUpdate(IWrapper wrapper, OnError onError)
    {
        String sql = wrapper.getSql();
        List<Object> params = wrapper.getParams();

        try
        {
            boolean result = super.executeUpdate(sql, params);
            this.onSuccess.onSuccess(sql, params);
            return result;
        } catch (Exception ex)
        {
            onError.OnError(ex, sql, params);
            return false;
        }

    }

    /**
     * 批量执行sql
     *
     * @param wrapperList
     * @return
     */
    public boolean executeBatchWrapper(Collection<IWrapper> wrapperList)
    {
        return this.executeBatchWrapper(wrapperList, this.onError);
    }


    /**
     * 批量执行sql
     *
     * @param wrapperList
     * @param onError
     * @return
     */
    public boolean executeBatchWrapper(Collection<IWrapper> wrapperList, OnError onError)
    {
        if (null == wrapperList || wrapperList.isEmpty())
        {
            return false;
        }

        String sql = null;
        List<Object> params = null;
        try
        {
            super.setAutoCommit(false);
            for (IWrapper iWrapper : wrapperList)
            {
                sql = iWrapper.getSql();
                params = iWrapper.getParams();
                executeUpdate(sql, params);
                this.onSuccess.onSuccess(sql, params);
            }

            super.commit();
            super.setAutoCommit(true);
            return true;
        } catch (Exception ex)
        {
            super.rollback();
            onError.OnError(ex, sql, params);
        }
        setAutoCommit(true);
        return false;
    }


    /**
     * 获取单个数据
     *
     * @param tableName
     * @param column
     * @param conditionField
     * @param condition
     * @return
     */
    public String getOneData(String tableName, String column, String conditionField, Object condition)
    {

        QueryWrapper wrapper = QueryWrapper.builder().tableName(tableName).column(column).conditionEQ(conditionField,
                condition);

        this.executeQuery(wrapper);
        if (this.first())
        {
            return this.getString(column);
        }
        return "";
    }


}
